import 'dart:async';

import 'package:async/async.dart';
import 'package:boss/ui/widget/loader/loader_error.dart';
import 'package:boss/ui/widget/loader/loader_loading.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

// 构建子widget回调
typedef LoaderBuilder = Widget Function(BuildContext context);
typedef LoaderTask<T> = Future<Result<T>> Function();

//加载数据Widget
class Loader<T> extends StatefulWidget {
  final FutureOr<T> initData; //初始化数据
  final LoaderTask<T> loadTask; //加载数据方法
  final Widget loadingWidget; //加载数据中widget
  final Widget failWidget; //加载数据错误widget
  final LoaderBuilder builder; //构建子widget回调
  final bool isInitData;

  @override
  LoaderState<T> createState() => LoaderState<T>();

  const Loader({
    Key key,
    @required this.loadTask,
    this.initData,
    this.loadingWidget,
    this.failWidget,
    @required this.builder,
    this.isInitData = true,
  }) : super(key: key);
}

class LoaderState<T> extends State<Loader<T>> {
  CancelableOperation _loadingTask; //加载数据控制器
  Result<T> value; //数据
  bool get isLoading => _loadingTask != null; //是否正在加载

  @override
  Loader<T> get widget => super.widget;

  @override
  void initState() {
    super.initState();
    // 如果存在默认数据则直接先使用默认数据渲染并重新拉取数据
    if (widget.initData != null) {
      scheduleMicrotask(() async {
        final data = await widget.initData;
        if (data != null) {
          await _onLoadData(Future.value(Result.value(data)));
        }
        _onRefresh();
      });
    } else if (widget.isInitData) {
      _onRefresh();
    }
  }

  @override
  void dispose() {
    _loadingTask?.cancel();
    _loadingTask = null;
    super.dispose();
  }

  //加载数据
  Future<Result<T>> _onLoadData(
    Future<Result<T>> future,
  ) {
    _loadingTask?.cancel();
    _loadingTask = CancelableOperation<Result<T>>.fromFuture(future)
      ..value
          .then((result) {
            value = result;
            setState(() {});
          })
          .catchError((e, stack) {})
          .whenComplete(() {
            _loadingTask = null;
          });

    setState(() {});
    return _loadingTask.value;
  }

  //刷新
  _onRefresh() async {
    await _onLoadData(widget.loadTask());
  }

  initData() async {
    await _onRefresh();
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, viewport) {
        //正在加载
        if (isLoading) {
          return widget.loadingWidget == null ? LoaderLoading() : widget.loadingWidget;
        }

        //正常渲染
        if (value != null && !value.isError) {
          return widget.builder(context);
        }

        //错误渲染
        if (value != null && value.isError) {
          return LoaderError(
            errorText: value.asError.error,
            onTap: _onRefresh,
          );
        }

        return Container();
      },
    );
  }
}
